home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-17 | 8.9 KB | 255 lines | [TEXT/CCL2] |
- ;;;
- ;;; drag-gray-region-lisp.lisp
- ;;;
-
- #|
- ================================================================
- Purpose ========================================================
- ================================================================
- Defines drag-gray-region-lisp .
-
-
- ================================================================
- Status =========================================================
- ================================================================
- Implemented.
-
- Copyright © 1990-92 Matthew Cornell. All Rights Reserved. Send
- bugs, comments, questions, and fixes to cornell@cs.umass.edu.
-
-
- ================================================================
- Change history =================================================
- ================================================================
- 02-Aug-92 mc Created.
- 04-Aug-92 mc Changed drag-gray-region-lisp's args to take pt-global-start,
- and to return the delta.
- 05-Aug-92 mc Fixed: Bug: If one clicks and moves quickly the mouse away
- from the click point, the gray region is offset from the mouse
- point.
- 15-Aug-92 mc Fixed drag-gray-region-lisp to clipt to port-wmgr's portRect.
- 17-Aug-92 mc Changed drag-gray-region-lisp to use #_DragGrayRgn .
-
- |#
-
-
- (in-package "CCL")
-
- (export '(DRAG-GRAY-REGION-LISP))
-
-
- ;;;================================================================
- ;;;
- ;;;================================================================
-
- ;;; Window-manager-port is from Apple's ift-macros.lisp:
-
- (defmacro window-manager-port ()
- '(%stack-block ((port 4))
- (require-trap #_GetWMgrPort :ptr port)
- (%get-ptr port)))
-
-
- (defgeneric drag-gray-region-lisp (macptr-region-global
- function
- pt-global-start
- &key cursor axis-constraint)
- (:documentation "A clean and simple lisp-level version of #_DragGrayRgn.
- Inverts macptr-region-global at the mouse position, destroying
- macptr-region-global in the process. macptr-region-global is drawn in
- the window manager's port so should be created relative to #@(0 0).
- Function is called each time the mouse moves; it takes one argument:
- pt-global-current, which is the current global mouse position. Cursor is
- a macptr of a cursor used during tracking, and defaults to
- *arrow-cursor*. axis-constraint is one of :no-constraint, :h-axis-only, or
- :v-axis-only. Returns a point that is the difference between the global
- point released at and pt-global-start."))
-
-
- (defmethod drag-gray-region-lisp ((macptr-region-global macptr)
- (function function)
- (pt-global-start integer)
- &key (cursor *arrow-cursor*)
- (axis-constraint :no-constraint))
- (declare (optimize speed))
- ;;
- ;; A version that uses #_DragGrayRgn .
- ;;
- (let* ((port-wmgr (window-manager-port))
- (macptr-portrect-wmgr (rref port-wmgr grafPort.portRect)))
- ;; Setup the call to proc-call-fcn then call #_DragGrayRgn .
- (setf *pt-global-last* pt-global-start
- *function-dragging* function)
- (with-cursor cursor
- (with-port port-wmgr
- (with-pen-saved
- (with-clip-rect macptr-portrect-wmgr
- ;; Make the call, which returns the resulting difference.
- (#_DragGrayRgn macptr-region-global pt-global-start
- macptr-portrect-wmgr macptr-portrect-wmgr
- (ecase axis-constraint
- (:no-constraint 0)
- (:h-axis-only 1)
- (:v-axis-only 2))
- proc-call-fcn)))))))
-
-
- (defvar *pt-global-last* 0
- "Used by proc-call-fcn to know when the mouse has moved.")
-
-
- (defvar *function-dragging*
- "Used by proc-call-fcn to know what function to call.")
-
-
- (defmacro funcall-saving-port (function port point)
- `(with-port ,port
- (with-pen-saved (funcall ,function ,point))))
-
-
- (defpascal proc-call-fcn ()
- (let* ((old-point *pt-global-last*)
- (pt-global-new (view-mouse-position nil))
- (moved? (/= old-point pt-global-new)))
- (when moved? (setf *pt-global-last* pt-global-new)
- (funcall-saving-port *function-dragging* (window-manager-port) pt-global-new))))
-
-
- ;;; Done.
-
- (provide "DRAG-GRAY-REGION-LISP")
-
-
- #| ;;; Define some example code.
-
-
- ;;; Global-to-local and local-to-global from "quickdraw.lisp" :
-
- (unless (fboundp 'global-to-local)
- (defmethod global-to-local ((view simple-view) h &optional v)
- (with-focused-view view
- (rlet ((p :point))
- (%put-long p (make-point h v))
- (#_GlobalToLocal p)
- (%get-long p)))))
-
- (unless (fboundp 'local-to-global)
- (defmethod local-to-global ((view simple-view) h &optional v)
- (with-focused-view view
- (rlet ((p :point))
- (%put-long p (make-point h v))
- (#_LocalToGlobal p)
- (%get-long p)))))
-
-
- (defmethod view-invert-marker ((view null) (pt-global integer))
- )
-
- (defmethod view-invert-marker ((view simple-view) (pt-global integer))
- ;; Invert a small box at pt-global, local to view.
- (let* ((pt-top-left-global (subtract-points pt-global #@(3 3)))
- (pt-bottom-right-global (add-points pt-top-left-global #@(6 6)))
- (pt-top-left (global-to-local view pt-top-left-global))
- (pt-bottom-right (global-to-local view pt-bottom-right-global)))
- (rlet ((rect :rect :topLeft pt-top-left :bottomRight pt-bottom-right))
- (with-focused-view view ;with-port (window-manager-port)
- (#_InvertRect rect))))
- ;; Invert a gray frame just inside view. (Headache if it's thick!)
- '(let* ((pt-top-left #@(0 0))
- (pt-bottom-right (view-size view)))
- (rlet ((rect :rect :topLeft pt-top-left :bottomRight pt-bottom-right))
- (with-focused-view view
- (with-pen-saved
- (#_PenMode (position :PATXOR *pen-modes*))
- (#_PenPat *gray-pattern*)
- (#_PenSize 3 3)
- (#_FrameRect rect))))))
-
-
- (defclass demo-view (button-dialog-item)
- ())
-
-
- (defmethod view-click-event-handler ((view demo-view) where)
- ;;
- (let* ((str-dialog-item-text-old (dialog-item-text view))
- (macptr-region-global (#_NewRgn))
- (pt-top-left (local-to-global view 0))
- (pt-bottom-right (local-to-global view (view-size view)))
- (pt-global-last (local-to-global (view-container view) where))
- (view-last (find-view-containing-point nil pt-global-last))
- pt-difference)
- (set-dialog-item-text view "Tracking…")
- ;;
- (rlet ((rect :rect :topLeft pt-top-left :bottomRight pt-bottom-right))
- (#_RectRgn macptr-region-global rect)
- ;; Invert initial:
- (view-invert-marker (find-view-containing-point nil pt-global-last)
- pt-global-last)
- (setf pt-difference
- (drag-gray-region-lisp
- macptr-region-global
- #'(lambda (pt-global-current)
- (when (option-key-p)
- (set-dialog-item-text
- view (format nil "~A ~A" (point-string pt-global-current)
- (type-of view-last))))
- ;; Invert old:
- (view-invert-marker view-last pt-global-last)
- (setf pt-global-last pt-global-current
- view-last (find-view-containing-point nil pt-global-current))
- ;; Invert new:
- (view-invert-marker view-last pt-global-last))
- pt-global-last
- :cursor *i-beam-cursor*
- :axis-constraint (cond ((shift-key-p) :h-axis-only)
- ((option-key-p) :v-axis-only)
- (t :no-constraint))))
- ;; Invert last then dispose.
- (view-invert-marker view-last pt-global-last)
- (#_DisposeRgn macptr-region-global))
- ;;
- (set-dialog-item-text view str-dialog-item-text-old)
- (print (point-string pt-difference))))
-
-
- ;;; Test.
-
- (defun test-drag ()
- (let* ((window
- (make-instance
- 'window :window-title "Test Drag"
- :view-position #@(420 40)
- :view-size #@(210 60)
- :view-subviews
- (list (make-instance 'demo-view
- :view-size #@(200 20)
- :view-font '("Geneva" 9)
- :dialog-item-text "Start Dragging (try Option key)")))))
- window))
-
-
- ;;; Test with scrollers.
-
- (require "SCROLLERS")
-
- (defun test-drag-scroller ()
- (let* ((window (make-instance
- 'window :window-title "Test Drag"
- :view-position #@(420 40)
- :view-size #@(170 150)))
- (scroller (make-instance 'scroller
- :view-container window
- :view-size #@(125 125)
- :track-thumb-p t))
- (demo-view (make-instance 'demo-view
- :view-position #@(50 50)
- :view-size #@(200 20)
- :view-font '("Geneva" 9)
- :dialog-item-text "Start Dragging (try Option key)"
- :view-container scroller)))
- (declare (ignore demo-view))
- ;;
- window))
-
- |#